#ifndef CPUBLICFUNC_H
#define CPUBLICFUNC_H

#include <vector>
#include <string>

#define PUBFUNC PubFunc::CPublicFunc
#define def_UNUSED(a) (void)(a)

typedef std::vector<std::string> VecStr;

namespace PubFunc {

//CRC16
class CCRC16Info
{
public:
    uint16_t    nPoly;          //多项式
    uint16_t    nInit;          //初始值
    uint16_t    nXorOut;        //结果异或值
    uint8_t     nRefIn;         //输入数据反转
    uint8_t     nRefOut;        //输出数据反转

    CCRC16Info()
    {
        nPoly = 0x1021;
        nInit = 0xFFFF;
        nXorOut = 0x0000;
        nRefIn = 0;
        nRefOut = 0;
    }
};

//CRC32
class CCRC32Info
{
public:
    uint32_t    nPoly;          //多项式
    uint32_t    nInit;          //初始值
    uint32_t    nXorOut;        //结果异或值
    uint8_t     nRefIn;         //输入数据反转
    uint8_t     nRefOut;        //输出数据反转

    CCRC32Info()
    {
        nPoly = 0x04C11DB7;
        nInit = 0xFFFFFFFF;
        nXorOut = 0xFFFFFFFF;
        nRefIn = 1;
        nRefOut = 1;
    }
};

class CPublicFunc
{
private:
    CPublicFunc() {}
    ~CPublicFunc() {}

public:
    //功能开关
    enum enumFunction
    {
        enOFF = 0,          //关闭
        enON,               //开启

        enDisable = 0,      //禁用
        enEnable,           //启用
    };

    //错误码
    enum enumErrCode
    {
        //all
        enOK = 0,                           //正确
        enFileOpenFailed,                   //文件打开失败
        enAllocErr,                         //内存耗尽，申请新内存失败

        //module manager
        enNoDrvFile = 100,                  //无此驱动文件
        enLoadFailed,                       //加载失败
        enDrvUnload,                        //模块未加载

        //tag manager
        enUnknowVersion = 200,              //未知版本
        enFirstLineEmpty,                   //首行为空
        enFirstLineFormatFailed,            //首行格式错误
        enTitleEmpty,                       //标题行为空
        enVerColUnknown,                    //版本列数量未知
        enColumnMismatch,                   //列数量不匹配
        enDuplicateName,                    //名称重复

        //tag
        enTagEmpty = 300,                   //测点名为空
        enTagTooLong,                       //测点名长度超限制
        enTagFormatErr,                     //测点格式错误
        enTagSpecialChar,                   //测点名包含不能识别的字符
        enTagNoConnectName,                 //无此连接名
        enTagNotExist,                      //点名不存在

        //opcua module
        enOPCUAClientNULL = 1000,           //客户端为空
        enOPCUAIpEmpty,                     //IP为空
        enOPCUAPortErr,                     //端口错误
        enOPCUAConnectFailed,               //客户端连接失败

        //other
        enUnknow = 10000,                   //未知错误
    };

    //排序方式枚举
    enum enumSortOrder
    {
        enAsc,      //顺序
        enDesc,     //逆序
    };

    //CRC校验类型
    enum enumCRCType
    {
        enCRC4_ITU,
        enCRC16_CCITT,
        enCRC16_CCITT_FALSE,
    };

public:
    //获取错误码具体信息
    static std::string getErrMsg(const int &nCode);

    // 跨平台文件存在检查
    static bool file_exists(const std::string& path);
    // 跨平台获取文件大小
    static long get_file_size(const std::string& path);
    // 跨平台路径分隔符处理
    static std::string extract_filename(const std::string& path);
    // 跨平台URL编码实现
    static std::string url_encode(const std::string &s);
    // 跨平台目录创建
    static bool create_directories(const std::string& path);
    // 跨平台文件读取
    static bool read_file(const std::string& path, std::string& out);
    //单层路径创建
    static bool createDirForSingle(const std::string &sPath);
    //判断路径是否存在，不存在则创建
    static bool createDirectory(const std::string &sPath);
    //判断目录是否存在
    static bool pathExists(const std::string &sPath);
    //判断文件是否存在
    static bool fileExists(const std::string &sFile);
    //使用时间戳+原始文件名保证唯一性
    static std::string generate_unique_filename(const std::string& original);

    //获取当前时间，并转成字符串（只能精确到秒）
    static std::string getFormatTime(const std::string &sFormat);
    //获取当前时间，并转成字符串（yyyy-MM-dd hh:mm:ss或yyyy-MM-dd hh:mm:ss:zzz）
    static std::string getNowTime(const bool &bMSec = false);
    //字符串用字符分割(bEmpty:是否清理空字符串，true:清理(默认)，false:不清理)
    static VecStr stringSplit(const std::string &src, char sep, const bool &bEmpty = true);
    //字符串用字符串分割(bEmpty:是否清理空字符串，true:清理(默认)，false:不清理)
    static VecStr stringSplit(const std::string &src, const std::string &sep,
                              const bool &bEmpty = true);
    //std::string转std::wstring
    static std::wstring strToWStr(const std::string &str);
    //std::wstring转std::string
    static std::string wStrToStr(const std::wstring &wStr);
    // 通用工具函数：小写转换
    static std::string toLower(const std::string& str);
    //遍历目录
    static void walkDirectory(const std::string& root, const std::string& target_ext,
                              std::vector<std::string>& results, const bool& bPath);
    //通过文件扩展名，发现文件
    static VecStr findFiles(const std::string& sPath, const std::string& targetExt, bool bPath = true);
    //获取运行目录
    static std::string currentPath();
    //获取文件所有数据
    static std::string getFileAllData(const std::string &sFile, std::string &sErrMsg, bool bBinary = false);
    //获取文件名称（不带路径和后缀）
    static std::string fileName(const std::string &sFile);
    //获取文件行数(默认以换行符计算，bSimple==false,逐字符解析，处理引号和转义逻辑)
    static int fileLines(const std::string &sFile, bool bSimple = true);
    //获取排序类型
    static int getOrder(const std::string &sOrder);
    //转16进制显示
    static std::string toStrHex(const std::string &str);
    static std::string toU16Hex(const uint16_t &value);
    static std::string toU32Hex(const uint32_t &value);
    // 反转一个字节 (8位)
    static uint8_t reflect8Bits(uint8_t byte);
    // 反转16位数据
    static uint16_t reflect16Bits(uint16_t value);
    // 反转32位数据
    static uint32_t reflect32Bits(uint32_t value);
    //CRC16校验
    static uint16_t crc16ForVec(const std::vector<uint8_t> &vec, CCRC16Info info = CCRC16Info());
    static uint16_t crc16ForString(const std::string &str, CCRC16Info info = CCRC16Info());

    //CRC32校验
    static uint32_t crc32ForVec(const std::vector<uint8_t> &vec, CCRC32Info info = CCRC32Info());
    static uint32_t crc32ForString(const std::string &str, CCRC32Info info = CCRC32Info());
};



}

#endif // CPUBLICFUNC_H
